package com.yeyks.common.exception;

import com.yeyks.common.ajax.AjaxResponseBody;
import com.yeyks.common.utils.SystemStrackUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@ControllerAdvice
@Slf4j
public class ExceptionHandle {
    /**
     * ServiceException 异常
     *
     * @param serviceException
     * @return
     */
    @ExceptionHandler(value = ServiceException.class)
    @ResponseBody
    public AjaxResponseBody<String> handle(ServiceException serviceException) {
        log.info("进入自定义异常：{}", serviceException.getMessage());
        SystemStrackUtil.logYyksExceptionStack(serviceException);
        if (serviceException.getCode() == null) {
            return AjaxResponseBody.failed(serviceException.getMessage());
        } else {
            return AjaxResponseBody.failed(serviceException.getCode(), serviceException.getMessage());
        }
    }

    /**
     * BindException 异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = BindException.class)
    @ResponseBody
    public AjaxResponseBody<String> handle(BindException e) {
        log.info("进入参数校验异常");
        String errorMsg = getErrorMsg(e);
        log.info("参数异常信息:{}", errorMsg);
        return AjaxResponseBody.failed(errorMsg);
    }

    /**
     * Exception 异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public AjaxResponseBody<String> handle(Exception e) {
        log.info("进入未知异常");
        e.printStackTrace();
        return AjaxResponseBody.failed("服务器异常");
    }

    /**
     * 从异常的map中得到异常信息
     *
     * @param bindException 错误对象
     * @return 返回消息结果
     */
    private String getErrorMsg(BindException bindException) {
        String msg = "参数验证失败";
        List<FieldError> errors = bindException.getBindingResult().getFieldErrors();
        Map<String, String> errorMap = errors.stream().collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage, (key, value) -> key));
        for (Map.Entry<String, String> entry : errorMap.entrySet()) {
            if (entry.getValue() != null && !entry.getValue().trim().equals("")) {
                msg = entry.getValue();
                break;
            }
        }
        return msg;
    }
}
